﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using Estructuras.Comunes;

namespace Estructuras.Consola.ConsolaAnalizarDatos
{
    /// <summary>
    /// Almacena las propiedades de un elemento específico.
    /// </summary>
    public class PAnalizarDatos : Propiedades
    {
        /// <summary>
        /// Entrada de datos.
        /// </summary>
        public string Entrada
        {
            get
            {
                return this.getPropiedadString(CAnalizarDatos.Entrada);
            }
            set
            {
                this.setOrAddPropiedad(CAnalizarDatos.Entrada, value);
            }
        }

        /// <summary>
        /// Salida de datos.
        /// </summary>
        public string Salida
        {
            get
            {
                return this.getPropiedadString(CAnalizarDatos.Salida);
            }
            set
            {
                this.setOrAddPropiedad(CAnalizarDatos.Salida, value);
            }
        }

        /// <summary>
        /// Estructura de entrada.
        /// </summary>
        public string EstructuraEntrada
        {
            get
            {
                return this.getPropiedadString(CAnalizarDatos.EstructuraEntrada);
            }
            set
            {
                this.setOrAddPropiedad(CAnalizarDatos.EstructuraEntrada, value);
            }
        }

        /// <summary>
        /// Estructura de salida.
        /// </summary>
        public string EstructuraSalida
        {
            get
            {
                return this.getPropiedadString(CAnalizarDatos.EstructuraSalida);
            }
            set
            {
                this.setOrAddPropiedad(CAnalizarDatos.EstructuraSalida, value);
            }
        }

        /// <summary>
        /// Salida de datos con palabras no encontradas.
        /// </summary>
        public string SalidaPalabrasNoEncontradas
        {
            get
            {
                return this.getPropiedadString(CAnalizarDatos.SalidaPalabrasNoEncontradas);
            }
            set
            {
                this.setOrAddPropiedad(CAnalizarDatos.SalidaPalabrasNoEncontradas, value);
            }
        }

        /// <summary>
        /// Salida de datos con patrones no encontrados.
        /// </summary>
        public string SalidaPatronesNoEncontrados
        {
            get
            {
                return this.getPropiedadString(CAnalizarDatos.SalidaPatronesNoEncontrados);
            }
            set
            {
                this.setOrAddPropiedad(CAnalizarDatos.SalidaPatronesNoEncontrados, value);
            }
        }

        /// <summary>
        /// Diccionario de alias asociados a los campos.
        /// </summary>
        public Dictionary<string, string> DiccionarioAliasCampos
        {
            get
            {
                return this.getPropiedadDiccionarioStringString(CAnalizarDatos.DiccionarioAliasCampos);
            }
            set
            {
                this.setOrAddPropiedad(CAnalizarDatos.DiccionarioAliasCampos, value);
            }
        }

        /// <summary>
        /// Lista de campos a analizar.
        /// </summary>
        public List<string> ListaCamposAnalizar
        {
            get
            {
                return this.getPropiedadListaString(CAnalizarDatos.ListaCamposAnalizar);
            }
            set
            {
                this.setOrAddPropiedad(CAnalizarDatos.ListaCamposAnalizar, value);
            }
        }

        /// <summary>
        /// Lista de caracteres separadores.
        /// </summary>
        public List<char> ListaSeparadores
        {
            get
            {
                return this.getPropiedadListaChar(CAnalizarDatos.ListaSeparadores);
            }
            set
            {
                this.setOrAddPropiedad(CAnalizarDatos.ListaSeparadores, value);
            }
        }

        /// <summary>
        /// Lista de caracteres especiales.
        /// </summary>
        public List<char> ListaCaracteresEspeciales
        {
            get
            {
                return this.getPropiedadListaChar(CAnalizarDatos.ListaEspeciales);
            }
            set
            {
                this.setOrAddPropiedad(CAnalizarDatos.ListaEspeciales, value);
            }
        }

        /// <summary>
        /// Lista de datos a eliminar.
        /// </summary>
        public List<string> ListaDatosEliminar
        {
            get
            {
                return this.getPropiedadListaString(CAnalizarDatos.ListaDatosEliminar);
            }
            set
            {
                this.setOrAddPropiedad(CAnalizarDatos.ListaDatosEliminar, value);
            }
        }

        /// <summary>
        /// Diccionario de datos a modificar.
        /// </summary>
        public Dictionary<string, string> DiccionarioDatosModificar
        {
            get
            {
                return this.getPropiedadDiccionarioStringString(CAnalizarDatos.DiccionarioDatosModificar);
            }
            set
            {
                this.setOrAddPropiedad(CAnalizarDatos.DiccionarioDatosModificar, value);
            }
        }

        /// <summary>
        /// Fichero definición de datos.
        /// </summary>
        public string DefinicionDatos
        {
            get
            {
                return this.getPropiedadString(CAnalizarDatos.DefinicionDatos);
            }
            set
            {
                this.setOrAddPropiedad(CAnalizarDatos.DefinicionDatos, value);
            }
        }

        /// <summary>
        /// Fichero definición de registros.
        /// </summary>
        public string DefinicionRegistros
        {
            get
            {
                return this.getPropiedadString(CAnalizarDatos.DefinicionRegistros);
            }
            set
            {
                this.setOrAddPropiedad(CAnalizarDatos.DefinicionRegistros, value);
            }
        }

        /// <summary>
        /// Constructor por defecto.
        /// </summary>
        public PAnalizarDatos()
            : base()
        {
        }

        /// <summary>
        /// Obtiene los parámetros a partir del fichero XML indicado.
        /// </summary>
        /// <param name="fichero">Fichero de configuración XML</param>
        override public void leer(string fichero)
        {
            base.leer(fichero);
            XmlDocument xml = LeerXml.AbrirFicheroParametros(fichero);

            this.Entrada = LeerXml.ObtenerValorCampo(xml, CAnalizarDatos.RutaEntrada);
            this.Salida = LeerXml.ObtenerValorCampo(xml, CAnalizarDatos.RutaSalida);
            this.EstructuraEntrada = LeerXml.ObtenerValorCampo(xml, CAnalizarDatos.RutaEstructuraEntrada);
            this.EstructuraSalida = LeerXml.ObtenerValorCampo(xml, CAnalizarDatos.RutaEstructuraSalida);
            // Configuracion
            this.SalidaPalabrasNoEncontradas = LeerXml.ObtenerValorCampo(xml, CAnalizarDatos.RutaSalidaPalabras);
            this.SalidaPatronesNoEncontrados = LeerXml.ObtenerValorCampo(xml, CAnalizarDatos.RutaSalidaPatrones);
            
            // Alias
            int numeroAlias = LeerXml.ObtenerNumeroNodosCampo(xml, CAnalizarDatos.RutaListaAlias);
            this.DiccionarioAliasCampos = new Dictionary<string, string>();
            for (int indiceAlias = 0; indiceAlias < numeroAlias; indiceAlias++)
            {
                string alias = LeerXml.ObtenerValorCampo(xml, CAnalizarDatos.RutaListaAlias, indiceAlias, CAnalizarDatos.NodoListaAliasAliasNombre);
                string campo = LeerXml.ObtenerValorCampo(xml, CAnalizarDatos.RutaListaAlias, indiceAlias, CAnalizarDatos.NodoListaAliasAliasCampo);
                this.DiccionarioAliasCampos.Add(alias, campo);
            }

            // Campos a analizar
            int numeroCampos = LeerXml.ObtenerNumeroNodosCampo(xml, CAnalizarDatos.RutaCamposAnalizar);
            this.ListaCamposAnalizar = new List<string>();
            for (int indiceCampo = 0; indiceCampo < numeroCampos; indiceCampo++)
            {
                string campo = LeerXml.ObtenerValorCampo(xml, CAnalizarDatos.RutaCamposAnalizar, indiceCampo);
                this.ListaCamposAnalizar.Add(campo);
            }

            // Separadores
            int numeroSeparadores = LeerXml.ObtenerNumeroNodosCampo(xml, CAnalizarDatos.RutaSeparadores);
            this.ListaSeparadores = new List<char>();
            for (int indiceSeparador = 0; indiceSeparador < numeroSeparadores; indiceSeparador++)
            {
                string separador = LeerXml.ObtenerValorCampo(xml, CAnalizarDatos.RutaSeparadores, indiceSeparador);
                char sep = separador[0];
                if (separador.Length > 1 && "\\t".Equals(separador))
                    sep = '\t';
                this.ListaSeparadores.Add(sep);
            }

            // Caracteres especiales
            int numeroCaracteres = LeerXml.ObtenerNumeroNodosCampo(xml, CAnalizarDatos.RutaCaracteresEspeciales);
            this.ListaCaracteresEspeciales = new List<char>();
            for (int indiceCaracter = 0; indiceCaracter < numeroCaracteres; indiceCaracter++)
            {
                string caracter = LeerXml.ObtenerValorCampo(xml, CAnalizarDatos.RutaCaracteresEspeciales, indiceCaracter);
                char car = caracter[0];
                if (caracter.Length > 1 && "\\t".Equals(caracter))
                    car = '\t';
                this.ListaCaracteresEspeciales.Add(car);
            }

            // Datos a eliminar
            int numeroDatos = LeerXml.ObtenerNumeroNodosCampo(xml, CAnalizarDatos.RutaListaEliminar);
            this.ListaDatosEliminar = new List<string>();
            for (int indiceDato = 0; indiceDato < numeroDatos; indiceDato++)
            {
                string dato = LeerXml.ObtenerValorCampo(xml, CAnalizarDatos.RutaListaEliminar, indiceDato);
                this.ListaDatosEliminar.Add(dato);
            }

            // Datos a modificar
            numeroDatos = LeerXml.ObtenerNumeroNodosCampo(xml, CAnalizarDatos.RutaListaModificar);
            this.DiccionarioDatosModificar = new Dictionary<string, string>();
            for (int indiceDato = 0; indiceDato < numeroDatos; indiceDato++)
            {
                string original = LeerXml.ObtenerValorCampo(xml, CAnalizarDatos.RutaListaModificar, indiceDato, CAnalizarDatos.NodoListaModificarModificacionOriginal);
                string nuevo = LeerXml.ObtenerValorCampo(xml, CAnalizarDatos.RutaListaModificar, indiceDato, CAnalizarDatos.NodoListaModificarModificacionNuevo);
                this.DiccionarioDatosModificar.Add(original, nuevo);
            }

            // Definicion de Datos
            this.DefinicionDatos = LeerXml.ObtenerValorCampo(xml, CAnalizarDatos.RutaDefinicionDatos);
            // Definicion de Registros
            this.DefinicionRegistros = LeerXml.ObtenerValorCampo(xml, CAnalizarDatos.RutaDefinicionRegistros);
        }
    }
}
